#ifndef SLEEABSTRACT_BDB_H
#define SLEEABSTRACT_BDB_H
#include <db_cxx.h>
#include <QString>
#include <QList>
#include <QVariant>
#include <QHash>
#include <QDir>
#include <QByteArray>
#include <QDate>
#include "sleedbglobal.h"

#define SLEEDB_VERS     0
#define SLEEHEADER_KEY  0

struct SleeDbHeader
{
    u_int32_t   key_qv_type;
    u_int32_t   slee_db_vers;
    u_int64_t   cntr;
    u_int64_t   fld_0;
    u_int64_t   fld_1;
} __attribute__((packed));

class SLEEDB_SHARED SleeAbstract_BDB
{
private:

protected:
         QDir m_qdirHome;
      QString m_qstrDbName;
         bool m_bDbOk;
         bool m_bReadOnly;
    u_int32_t m_dbOpenFlags;
          Db* m_pDb;
         Dbc* m_header_cur;
 SleeDbHeader m_header;
        void read_header();
        void write_header();
        void set_header_defaults();
    QVariant genId();
        bool match_key_type(QVariant &qv_key);
        void setId(u_int64_t id);
virtual void pre_initDb() = 0;
virtual void post_initDb() = 0;
virtual void pre_closeDb() = 0;

    inline static void dbt_to_qb(QByteArray &qb_data, const Dbt &data) {qb_data = QByteArray((const char *)data.get_data(), data.get_size());}
    inline static void dbt_to_qb(QByteArray &qb_data, const Dbt *pdata) {qb_data = QByteArray((const char *)pdata->get_data(), pdata->get_size());}
    inline static void qb_to_dbt(QByteArray &qb_data, Dbt &data) {data.set_data((void *)qb_data.data()); data.set_size(qb_data.size());}
    inline static void qb_to_dbt(QByteArray &qb_data, Dbt *pdata) {pdata->set_data((void *)qb_data.data()); pdata->set_size(qb_data.size());}

    static bool isDbtSpec(const Dbt &data) {if(data.get_size() != sizeof(u_int64_t)) return false; if(*((u_int64_t *)data.get_data())) return false; return true; }
    static bool isDbtSpec(const Dbt *p_data) {return isDbtSpec(*p_data);}


    static void qv_to_qb(QByteArray &buffer, const QVariant &qv_data);
    static void qb_to_qv(QByteArray &buffer, QVariant &qv_data);

    inline static void qv_to_dbt(QByteArray &qb_data, const QVariant &qv_data, Dbt &data) {qb_data.clear(); qv_to_qb(qb_data, qv_data); qb_to_dbt(qb_data, data);}
    inline static void qv_to_dbt(QByteArray &qb_data, const QVariant &qv_data, Dbt *pdata) {qv_to_dbt(qb_data, qv_data, *pdata);}

    inline static void dbt_to_qv(const Dbt &data, QVariant &qv_data) {QByteArray qb_data; dbt_to_qb(qb_data, data); qb_to_qv(qb_data, qv_data);}
    inline static void dbt_to_qv(const Dbt *pdata, QVariant &qv_data) {dbt_to_qv(*pdata, qv_data);}

    static int cmpr_var_keys(Db *pDb, const Dbt *pkey1, const Dbt * pkey2);
    static int cmpr_dup_sort(Db *pDb, const Dbt *pkey1, const Dbt * pkey2);


public:
    static int cmpr_qvariants(const QVariant &qv_a_data, const QVariant &qv_b_data);

    SleeAbstract_BDB();
    virtual int initDb(const QString &qstrHomeDir, const QString &qstrDbName, bool bReadOnlyMode = false);
    virtual int closeDb();
};

#endif // SLEEABSTRACT_BDB_H
